package com.googlecode.datawander.connectors;

import com.db4o.Db4o;
import com.db4o.ObjectContainer;
import com.db4o.ObjectServer;
import com.db4o.config.Configuration;
import com.db4o.defragment.Defragment;
import com.db4o.defragment.DefragmentConfig;
import com.db4o.defragment.StoredClassFilter;
import com.db4o.ext.StoredClass;
import com.db4o.reflect.jdk.JdkReflector;
import java.io.IOException;
import java.math.BigDecimal;
/**
 * Version for db4o 7.4
 * @author MarcinStachniuk
 */
public class Db4oUtil {
    private static String databaseFilename = "";
    private static ObjectServer objectServer;
    private static final ThreadLocal<ObjectContainer> dbThreadLocal = new ThreadLocal<ObjectContainer>();

    public static ObjectContainer getObjectContainer() {
        ObjectContainer oc = (ObjectContainer) dbThreadLocal.get();
        if (oc == null || oc.ext().isClosed()) {
            Configuration conf = Db4o.newConfiguration();

            //conf.reflectWith(new JdkReflector(Thread.currentThread().getContextClassLoader()));

            System.out.println("Db4oUtil open database "+databaseFilename);

            conf.activationDepth(Integer.MAX_VALUE);
            // save BigDecimal in db4o 7.4
            conf.objectClass(BigDecimal.class).callConstructor(true);
            conf.objectClass(BigDecimal.class).storeTransientFields(true);
            oc = Db4o.openFile(conf, databaseFilename);
            dbThreadLocal.set(oc);
        }
        return oc;
    }

    public static void closeObjectContainer() {
        ObjectContainer oc = (ObjectContainer) dbThreadLocal.get();
        dbThreadLocal.set(null);
        if (oc != null) oc.close();
    }

    public static void shutdown() {
        if (objectServer != null) {
            objectServer.close();
        }
    }

    public static String getDatabaseFilename() {
        return databaseFilename;
    }

    public static void setDatabaseFilename(String databaseFilename) {
        Db4oUtil.databaseFilename = databaseFilename;
    }

    public static void defragDatabase() throws IOException {
        DefragmentConfig config = new DefragmentConfig(Db4oUtil.getDatabaseFilename());
        config.forceBackupDelete(true);
        config.storedClassFilter(new StoredClassFilter() {
            public boolean accept(StoredClass sc) {
                if(sc.instanceCount() == 0) {
                    return false;
                }
                return true;
            }
        });
        Defragment.defrag(config);
    }
}
